<template>
  <ContentContainer :show-footer="false" inner>
    <a-form
      ref="formRef"
      :model="formState"
      :rules="rules"
      layout="vertical"
      class="w-100!">
      <a-form-item
        label="节点名称"
        field="name"
        asterisk-position="end"
        hide-asterisk>
        <a-input
          v-model="formState.name"
          placeholder="请输入节点名称"></a-input>
      </a-form-item>
      <a-form-item
        label="区域"
        field="region_id"
        asterisk-position="end"
        hide-asterisk>
        <a-select
          v-model="formState.region_id"
          :options="areaListOptions"
          placeholder="请选择区域"></a-select>
      </a-form-item>
      <a-form-item
        field="cascade_level"
        asterisk-position="end"
        class="level-item"
        hide-asterisk>
        <template #label>
          <span>节点层级</span>
          <a-tooltip :content-style="{ 'max-width': 'none' }">
            <i-icons-question class="question-icon" />
            <template #content>
              <span>
                1. L2 节点负责回源，L1 节点自动从 L2 节点获取源站数据。
              </span>
              <br />
              <span> 2. 如果没有 L2 节点，L1 节点直接向源站请求回源。 </span>
            </template>
          </a-tooltip>
        </template>
        <a-radio-group v-model="formState.cascade_level">
          <a-radio :value="1">L1</a-radio>
          <a-radio :value="2">L2</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item
        v-if="formState.cascade_level === 2"
        field="cascade_ip"
        asterisk-position="end"
        class="level-item"
        hide-asterisk>
        <template #label>
          <span>级联IP</span>
          <a-tooltip :content-style="{ 'max-width': 'none' }">
            <i-icons-question class="question-icon" />
            <template #content>
              <span> L1 节点回源当前 L2 节点时将会使用该 IP 地址。 </span>
            </template>
          </a-tooltip>
        </template>
        <a-select
          v-model="formState.cascade_ip"
          :options="ipOptions"
          placeholder="请选择级联IP"></a-select>
      </a-form-item>
      <a-form-item
        v-if="formState.cascade_level === 2"
        field="cascade_port"
        asterisk-position="end"
        class="level-item"
        hide-asterisk>
        <template #label>
          <span>级联端口</span>
          <a-tooltip>
            <i-icons-question class="question-icon" />
            <template #content>
              <span> L1 节点回源当前 L2 节点时将会使用该端口，不能为8888 </span>
            </template>
          </a-tooltip>
        </template>
        <a-input-number
          v-model="formState.cascade_port"
          :max="65535"
          :precision="0"
          placeholder="请输入端口">
        </a-input-number>
      </a-form-item>
      <a-form-item
        field="ips"
        asterisk-position="end"
        class="level-item node-ip">
        <template #label>
          <span>节点 IP</span>
          <a-tooltip>
            <i-icons-question class="question-icon" />
            <template #content>
              <span>
                1. 如果您的网卡为弹性网卡，可能会造成系统获取节点 IP
                错误，请根据实际情况填写；
              </span>
              <br />
              <span> 2. 请确保节点 IP 能在公网正常访问 </span>
            </template>
          </a-tooltip>
          <div class="node-ip-label" @click="open">
            <i-icons-cloud-download />
            获取 IP
          </div>
        </template>
        <a-table
          :columns="tableColumn"
          :data="formState.ips"
          :pagination="false">
          <template #ip="{ record, rowIndex }">
            <a-form-item
              :field="`ips[${rowIndex}].ip`"
              hide-asterisk
              :rules="nodeIpRules"
              validate-trigger="blur">
              <a-input
                v-model="record.ip"
                placeholder="请输入节点 IP"></a-input>
            </a-form-item>
          </template>
          <template #action="{ rowIndex }">
            <a-link v-if="rowIndex === 0" :hoverable="false" disabled
              >当前为主 IP</a-link
            >
            <a-link
              v-else
              :hoverable="false"
              @click="handleTableCommand('set_main', rowIndex)"
              >设置为主 IP</a-link
            >
            <a-link
              :hoverable="false"
              status="danger"
              :disabled="rowIndex === 0"
              @click="handleTableCommand('delete', rowIndex)"
              >移除</a-link
            >
          </template>
          <template #footer>
            <a-button
              class="flex items-center gap-x-2 w-fit"
              type="text"
              status="normal"
              :disabled="formState.ips.length > 9"
              @click="handleTableCommand('add')">
              <i-icons-table-add />
              添加节点 IP
            </a-button>
          </template>
        </a-table>
      </a-form-item>
    </a-form>
    <a-button type="primary" class="mt-6" @click="save">保存配置</a-button>
    <NewIp
      v-model="visible"
      v-model:ips="formState.ips"
      :report-ips="formState?.report_ip"></NewIp>
  </ContentContainer>
</template>

<script lang="ts" setup>
import { getApiNodeApi, updateApiNodeApi } from '@/apis/modules/node'
import useGroupArea from '@/views/site/hooks/useGroupArea'
import type { FieldRule, FormInstance } from '@arco-design/web-vue'
import NewIp from '../../components/NewIp.vue'

type FormDataType = {
  id: string
  name: string
  region_id: string
  cascade_level: number
  cascade_ip: string
  report_ip: string[]
  ips: Array<{ ip: string }>
  cascade_port: number
}
const route = useRoute()
const { visible, open } = usePopup()
const nodeId = computed(() => route.params.id as string)
const formState = reactive<FormDataType>({
  id: '',
  name: '',
  region_id: '',
  cascade_level: 1,
  cascade_ip: '',
  ips: [],
  report_ip: [],
  cascade_port: 1
})
const formRef = ref<FormInstance>()
const ipOptions = ref<LabelValue[]>([])
const { areaListOptions } = useGroupArea('region')
const rules = computed<Record<string, FieldRule>>(() => ({
  name: {
    required: true,
    validator(value, callback) {
      if (!value) {
        return callback('请输入节点名称')
      } else if (value.length < 4 || value.length > 32) {
        return callback('节点名称长度为4-32个字符')
      }
      callback()
    }
  },
  region_id: { required: true, message: '请选择区域' },
  cascade_level: { required: true, message: '请选择节点层级' },
  cascade_port: { required: true, message: '请输入级联端口' }
}))
const nodeIpRules: FieldRule = {
  required: true,
  validator: (value, callback) => {
    if (!value) {
      return callback('IP不能为空')
    }
    if (!regexpMap.ipv4.test(value)) {
      return callback('IP格式不正确')
    }
    callback()
  }
}
const tableColumn = buildColumns([
  {
    title: '节点IP',
    slotName: 'ip'
  },
  {
    title: '操作',
    slotName: 'action',
    cellClass: 'actions-cell',
    width: 160
  }
])

const handleTableCommand = (command: string, index?: number) => {
  const map: Record<string, any> = {
    add: () => {
      formState.ips.push({
        ip: ''
      })
    },
    delete: () => {
      formState.ips!.splice(index!, 1)
    },
    set_main: () => {
      const mainIp = formState.ips[index!]
      if (!regexpMap.ipv4.test(mainIp.ip) && !mainIp.ip) {
        return
      }
      formState.ips.splice(index!, 1)
      formState.ips.unshift(mainIp)
    }
  }
  map[command] && map[command]()
}

const getNodeInfo = () => {
  // 获取节点信息
  getApiNodeApi({ id: nodeId.value }).then((res) => {
    formState.region_id = res.region_info!.id!
    formState.name = res.name!
    formState.cascade_level = res.cascade_level!
    formState.ips =
      res.ips?.map((item) => ({ ip: item ?? '' })).filter(Boolean) ?? []
    ipOptions.value =
      res.ips?.map((item) => ({ label: item ?? '', value: item ?? '' })) ?? []
    ipOptions.value.unshift({ label: '使用主IP', value: '' })
    formState.cascade_ip = res.cascade_ip ?? ''
    formState.cascade_port = res.cascade_port ?? 0
    formState.report_ip = res.report_ip ?? []
  })
}

const save = async () => {
  const error = await formRef.value?.validate()
  if (error) return
  const ips = formState.ips.map((item) => item.ip).filter(Boolean)
  let data: any = {
    name: formState.name,
    region_id: formState.region_id,
    cascade_level: formState.cascade_level,
    ips: ips,
    id: nodeId.value
  }
  if (formState.cascade_level === 2) {
    data = {
      ...data,
      cascade_port: formState.cascade_port,
      cascade_ip: formState.cascade_ip
    }
  }
  let checkPass = true
  const report_ips = formState.report_ip ?? []
  for (let i = 0; i < ips.length; i++) {
    const index = report_ips.findIndex((item) => item === ips[i])
    if (index < 0) {
      checkPass = false
      break
    }
  }

  const fn = () =>
    updateApiNodeApi(data).then(() => {
      ToastUtils.success('保存成功')
      getNodeInfo()
    })
  if (!checkPass) {
    CloudModal.confirm(
      {
        content: '公网IP与系统识别的不符，可能造成异常，确定要保存吗？'
      },
      fn
    )
    return
  }
  fn()
}
watch(
  () => route.params.id,
  (v) => {
    if (v) {
      getNodeInfo()
    }
  },
  {
    immediate: true
  }
)
</script>
<style lang="less" scoped>
.arco-form {
  .level-item :deep(.arco-form-item-label) {
    display: flex;
    align-items: center;
    column-gap: 4px;
  }
  .node-ip:deep(.arco-form-item-label) {
    width: 100%;
    .node-ip-label {
      @apply flex items-center gap-x-1 flex-1 text-primary order-2 justify-end cursor-pointer;
    }
  }
}
</style>
